/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
 *
 */
import path from 'path';

import { expect } from '@jest/globals';
import * as execa from 'execa';
import fse from 'fs-extra';

import { getJson5Obj } from '../../../../src/utils/json-util';
import { initExecuteCommand, runHvigorAsync } from '../../common/common';
import { cleanTarget } from '../../plugins/common-fun';
import {
  AbilityType,
  APIType,
  APIVersion,
  CaseLevel,
  LanguageType,
  ModuleTemplateType,
  RuntimeOSType,
  SDKType,
} from '../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../plugins/task-builder/task-case-builder';
import { ProjectBuildOption, TestCaseFun } from '../../plugins/task-builder/test-case';
import { TestTaskOptionBuilder } from '../../plugins/task-builder/test-task-option';

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: APIVersion.API11,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.EmptyAbility,
  },
  modulesOption: [ModuleTemplateType.StaticLibrary],
};

const testFun: TestCaseFun = async (project, taskConfig, record) => {
  const projectRootPath = project.projectRootPath();
  const harModule = project.getModule('staticLibrary');
  const harRootPath = harModule.moduleRootPath();
  const buildProfilePath = path.resolve(harRootPath, 'build-profile.json5');
  const buildProfileObj = getJson5Obj(buildProfilePath);
  buildProfileObj.buildOption.packingOptions = {
    asset: {
      include: ['router.json5', './src/router.json5', 'config', '.test'],
      exclude: ['./config/dir'],
    },
  };
  fse.writeFileSync(buildProfilePath, JSON.stringify(buildProfileObj, null, 2));
  //   写入文件
  fse.writeFileSync(path.resolve(harRootPath, 'router.json5'), '{}');
  fse.writeFileSync(path.resolve(harRootPath, './src/router.json5'), '{}');
  fse.writeFileSync(path.resolve(harRootPath, './src/router1.json5'), '{}');
  fse.ensureDirSync(path.resolve(harRootPath, 'config/dir'));
  fse.writeFileSync(path.resolve(harRootPath, './config/test.txt'), 'testText');
  fse.writeFileSync(path.resolve(harRootPath, './config/dir/test1.txt'), 'testText1');
  fse.ensureDirSync(path.resolve(harRootPath, '.test'));
  fse.writeFileSync(path.resolve(harRootPath, '.test/test2.txt'), 'testText2');

  const command = initExecuteCommand({
    mode: 'module',
    product: 'default',
    tasks: 'assembleHar',
    buildMode: 'release',
  });
  const result = await runHvigorAsync(projectRootPath, command);
  record.addStep('assemble HAR, 检查产物中是否有对应的文件', result);
  expect(result.stdout).toContain('BUILD SUCCESSFUL');
  // 解析entry的hap包
  const outputDir = await parse(path.resolve(harRootPath, 'build/default/outputs/default/staticLibrary.har'));
  expect(fse.existsSync(path.resolve(outputDir, 'package/router.json5'))).toEqual(true);
  expect(fse.existsSync(path.resolve(outputDir, 'package/src/router.json5'))).toEqual(true);
  expect(fse.existsSync(path.resolve(outputDir, 'package/config/test.txt'))).toEqual(true);
  // 不在收集集里的文件
  expect(fse.existsSync(path.resolve(outputDir, 'package/src/router1.json5'))).toEqual(false);
  // 被exclude的文件
  expect(fse.existsSync(path.resolve(outputDir, 'package/config/dir/test1.txt'))).toEqual(false);
  // 清理产物
  await cleanTarget(project);

  const projectBuildProfile = path.resolve(projectRootPath, 'build-profile.json5');
  const projectBuildProfileJson = getJson5Obj(projectBuildProfile);
  projectBuildProfileJson.app.products[0] = {
   ...(projectBuildProfileJson.app.products[0]),
   "buildOption": {
     "strictMode": {
       "useNormalizedOHMUrl": false
     }
   }
  }
  const result1 = await runHvigorAsync(projectRootPath, command);
  record.addStep('assemble HAR, 检查.test文件夹是否在har包中', result1);

  // .test文件夹不被打包
  expect(fse.existsSync(path.resolve(outputDir, 'package/.test'))).toEqual(false);
  expect(fse.existsSync(path.resolve(outputDir, 'package/.test/test2.txt'))).toEqual(false);
};

async function parse(harOutPath: string) {
  const dir = path.dirname(harOutPath);
  let fileName = path.basename(harOutPath);
  fileName = fileName.replace(fileName.slice(-3), 'tgz');
  const zipPath = path.resolve(dir, fileName);

  // 将生成的har包复制为tgz包
  fse.copyFileSync(harOutPath, zipPath);
  // 解压zip，解析出生成har里的内容
  const outputDir = zipPath.replace(path.join('outputs', 'default','staticLibrary.tgz'), '');
  // 通过命令行解压tgz
  await execa.command(`tar zxvf ${zipPath} -C ${outputDir}`);
  return outputDir;
}

TestCaseBuilder.builder()
  .caseName('HAR_MODULE_BUILD_PROFILE_PACKING_OPTIONS_ASSET_E2E')
  .description('字节码har&混淆源码har打包逻辑优化')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(TestTaskOptionBuilder.builder().caseLevel(CaseLevel.AR).build())
  .testFun(testFun)
  .load();
